/*
 * ESPRESSIF MIT License
 *
 * Copyright (c) 2021 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
 *
 * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
 * it is free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#ifndef _ES7210_H
#define _ES7210_H

#include "audio_hal.h"

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */

#define ES7210_RESET_REG00           0x00  /* Reset control */
#define ES7210_CLOCK_OFF_REG01       0x01  /* Used to turn off the ADC clock */
#define ES7210_MAINCLK_REG02         0x02  /* Set ADC clock frequency division */
#define ES7210_MASTER_CLK_REG03      0x03  /* MCLK source $ SCLK division */
#define ES7210_LRCK_DIVH_REG04       0x04  /* lrck_divh */
#define ES7210_LRCK_DIVL_REG05       0x05  /* lrck_divl */
#define ES7210_POWER_DOWN_REG06      0x06  /* power down */
#define ES7210_OSR_REG07             0x07
#define ES7210_MODE_CONFIG_REG08     0x08  /* Set master/slave & channels */
#define ES7210_TIME_CONTROL0_REG09   0x09  /* Set Chip intial state period*/
#define ES7210_TIME_CONTROL1_REG0A   0x0A  /* Set Power up state period */
#define ES7210_SDP_INTERFACE1_REG11  0x11  /* Set sample & fmt */
#define ES7210_SDP_INTERFACE2_REG12  0x12  /* Pins state */
#define ES7210_ADC_AUTOMUTE_REG13    0x13  /* Set mute */
#define ES7210_ADC34_MUTERANGE_REG14 0x14  /* Set mute range */
#define ES7210_ADC12_MUTERANGE_REG15 0x15  /* Set mute range */
#define ES7210_ADC34_HPF2_REG20      0x20  /* HPF */
#define ES7210_ADC34_HPF1_REG21      0x21
#define ES7210_ADC12_HPF1_REG22      0x22
#define ES7210_ADC12_HPF2_REG23      0x23
#define ES7210_ANALOG_REG40          0x40  /* ANALOG Power */
#define ES7210_MIC12_BIAS_REG41      0x41
#define ES7210_MIC34_BIAS_REG42      0x42
#define ES7210_MIC1_GAIN_REG43       0x43
#define ES7210_MIC2_GAIN_REG44       0x44
#define ES7210_MIC3_GAIN_REG45       0x45
#define ES7210_MIC4_GAIN_REG46       0x46
#define ES7210_MIC1_POWER_REG47      0x47
#define ES7210_MIC2_POWER_REG48      0x48
#define ES7210_MIC3_POWER_REG49      0x49
#define ES7210_MIC4_POWER_REG4A      0x4A
#define ES7210_MIC12_POWER_REG4B     0x4B  /* MICBias & ADC & PGA Power */
#define ES7210_MIC34_POWER_REG4C     0x4C

typedef enum {
    ES7210_AD1_AD0_00 = 0x80,
    ES7210_AD1_AD0_01 = 0x82,
    ES7210_AD1_AD0_10 = 0x84,
    ES7210_AD1_AD0_11 = 0x86
} es7210_address_t;

typedef enum {
    ES7210_INPUT_MIC1 = 0x01,
    ES7210_INPUT_MIC2 = 0x02,
    ES7210_INPUT_MIC3 = 0x04,
    ES7210_INPUT_MIC4 = 0x08
} es7210_input_mics_t;

typedef enum gain_value {
    GAIN_0DB = 0,
    GAIN_3DB,
    GAIN_6DB,
    GAIN_9DB,
    GAIN_12DB,
    GAIN_15DB,
    GAIN_18DB,
    GAIN_21DB,
    GAIN_24DB,
    GAIN_27DB,
    GAIN_30DB,
    GAIN_33DB,
    GAIN_34_5DB,
    GAIN_36DB,
    GAIN_37_5DB,
} es7210_gain_value_t;

/**
 * @brief  Initialize ES7210 ADC chip
 *
 * @param[in]  codec_cfg  configuration of ES7210
 *
 * @return
 *       - ESP_OK
 *       - ESP_FAIL
 */
esp_err_t es7210_adc_init(audio_hal_codec_config_t *codec_cfg);

/**
 * @brief  Deinitialize ES7210 ADC chip
 *
 * @return
 *       - ESP_OK
 *       - ESP_FAIL
 */
esp_err_t es7210_adc_deinit();

/**
 * @brief  Configure ES7210 ADC mode and I2S interface
 *
 * @param[in]  mode   codec mode
 * @param[in]  iface  I2S config
 *
 * @return
 *       - ESP_FAIL  Parameter error
 *       - ESP_OK    Success
 */
esp_err_t es7210_adc_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface);

/**
 * @brief  Control ES7210 ADC chip
 *
 * @param[in]  mode        codec mode
 * @param[in]  ctrl_state  start or stop progress
 *
 * @return
 *       - ESP_FAIL  Parameter error
 *       - ESP_OK    Success
 */
esp_err_t es7210_adc_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state);

/**
 * @brief  Set gain (Note: the enabled microphone sets the same gain)
 *
 * @param[in]  mic_select  mic select. eg: ES7210_INPUT_MIC1 | ES7210_INPUT_MIC2
 * @param[in]  gain        gain
 *
 *                         gain        :   value
 *                         GAIN_0DB    :   1
 *                         GAIN_3DB    :   2
 *                         GAIN_6DB    :   3
 *                         ·
 *                         ·
 *                         ·
 *                         GAIN_30DB   :   10
 *                         GAIN_33DB   :   11
 *                         GAIN_34_5DB :   12
 *                         GAIN_36DB   :   13
 *                         GAIN_37_5DB :   14
 *
 * @return
 *       - ESP_OK
 *       - ESP_FAIL
 */
esp_err_t es7210_adc_set_gain(es7210_input_mics_t mic_select, es7210_gain_value_t gain);

/**
 * @brief  Get adcn gain
 *
 * @param[in]  mic_select  Selected mic
 * @param[in]  gain        gain value
 *
 * @return
 *       - ESP_OK
 */
esp_err_t es7210_adc_get_gain(es7210_input_mics_t mic_select, int *gain);

/**
 * @brief  Print all adc gain
 *
 * @return
 *       - ESP_OK
 */
esp_err_t es7210_adc_print_gains(void);

/**
 * @brief  Set volume
 *
 * @param[in]  volume  volume
 *
 * @return
 *       - ESP_OK
 */
esp_err_t es7210_adc_set_volume(int volume);

/**
 * @brief  Set ES7210 ADC mute status
 *
 * @return
 *       - ESP_FAIL
 *       - ESP_OK
 */
esp_err_t es7210_set_mute(bool enable);

/**
 * @brief  Select ES7210 mic
 *
 * @param[in]  mic_select  mics
 *
 * @return
 *       - ESP_FAIL
 *       - ESP_OK
 */
esp_err_t es7210_mic_select(es7210_input_mics_t mic_select);

/**
 * @brief  Read all regs of ES7210
 */
void es7210_read_all(void);

#ifdef __cplusplus
}
#endif  /* __cplusplus */

#endif  /* _ES7210_H_ */
